﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;

namespace YJKRevitDimensionText.OneKeyPlanDim.OutWallThreeDim
{
	public class ParallelLinesUtils
	{
		public static List<Curve> SortHoriLineWithVector(List<Curve> lstHoriLine, XYZ vecDir)
		{
			List<Curve> list = new List<Curve>();
			try
			{
				List<XYZ> list2 = new List<XYZ>();
				foreach (Curve curve in lstHoriLine)
				{
					list2.Add(curve.GetEndPoint(0));
				}
				List<XYZ> list3 = ParallelLinesUtils.SortPointsWithVector(list2, vecDir);
				List<Curve> list4 = new List<Curve>();
				list4.AddRange(lstHoriLine);
				foreach (XYZ xyz in list3)
				{
					foreach (Curve curve2 in list4)
					{
						if (xyz.IsAlmostEqualTo(curve2.GetEndPoint(0)))
						{
							list.Add(curve2);
							list4.Remove(curve2);
							break;
						}
					}
				}
			}
			catch (Exception)
			{
				return lstHoriLine;
			}
			return list;
		}

		public static bool GetParallelLinesMaxDisEndPoint(List<Line> lstParalLine, out XYZ ptMin, out XYZ ptMax, double dMinExtend = 0.0, double dMaxExtend = 0.0)
		{
			ptMin = null;
			ptMax = null;
			try
			{
				XYZ vecDir = Transform.CreateRotation(XYZ.BasisZ, Math.PI*.5).OfVector(lstParalLine.First<Line>().Direction.Normalize());
				List<Curve> source = ParallelLinesUtils.SortHoriLineWithVector(lstParalLine.Cast<Curve>().ToList<Curve>(), vecDir);
				Curve curve = source.First<Curve>();
				Curve curve2 = source.Last<Curve>().Clone();
				curve2.MakeUnbound();
				XYZ endPoint = curve.GetEndPoint(0);
				XYZ xyzpoint = curve2.Project(endPoint).XYZPoint;
				if (endPoint != null && xyzpoint != null)
				{
					XYZ xyz = (xyzpoint - endPoint).Normalize();
					XYZ xyz2 = -xyz;
					ptMin = endPoint + xyz2.Multiply(dMinExtend);
					ptMax = xyzpoint + xyz.Multiply(dMaxExtend);
				}
			}
			catch (Exception)
			{
				return false;
			}
			return true;
		}

		public static List<XYZ> RemoveDuplicatedPoint(List<XYZ> lstPoint)
		{
			List<XYZ> list = new List<XYZ>();
			list.AddRange(lstPoint);
			for (int i = 0; i < list.Count; i++)
			{
				XYZ xyz = list[i];
				for (int j = i + 1; j < list.Count; j++)
				{
					if (list[j].IsAlmostEqualTo(xyz))
					{
						list.RemoveAt(j);
						j--;
					}
				}
			}
			return list;
		}

		public static List<XYZ> SortPointsWithVector(List<XYZ> srcPoints, XYZ vecDirection)
		{
			List<XYZ> list = new List<XYZ>();
			List<XYZ> list2 = new List<XYZ>();
			list.AddRange(srcPoints);
			SortedList<double, List<XYZ>> sortedList = new SortedList<double, List<XYZ>>();
			XYZ xyz = vecDirection.Multiply(1.0);
			foreach (XYZ xyz2 in srcPoints)
			{
				double d = xyz.AngleTo(xyz2);
				double key = Math.Sqrt(xyz2.X * xyz2.X + xyz2.Y * xyz2.Y + xyz2.Z * xyz2.Z) * Math.Cos(d);
				if (!sortedList.ContainsKey(key))
				{
					sortedList.Add(key, new List<XYZ>
					{
						xyz2
					});
				}
				else
				{
					sortedList[key].Add(xyz2);
				}
			}
			if (sortedList.Count > 0)
			{
				IEnumerator<KeyValuePair<double, List<XYZ>>> enumerator2 = sortedList.GetEnumerator();
				while (enumerator2.MoveNext())
				{
					List<XYZ> list3 = list2;
					KeyValuePair<double, List<XYZ>> keyValuePair = enumerator2.Current;
					list3.AddRange(keyValuePair.Value);
				}
				if (list2.Count == srcPoints.Count)
				{
					list = list2;
				}
			}
			return list;
		}
	}
}
